<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chat Interface with Streaming & Context</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: auto;
            padding: 10px;
        }
        #chatBox {
            border: 1px solid #ccc;
            padding: 10px;
            height: 400px;
            overflow-y: scroll;
            margin-bottom: 10px;
        }
        .message {
            padding: 5px;
            border-radius: 5px;
            margin-bottom: 5px;
            white-space: pre-wrap; /* 保留换行 */
        }
        .user {
            background-color: #e0f7fa;
            text-align: right;
        }
        .assistant {
            background-color: #e8f5e9;
        }
        #userInput {
            width: 100%;
            padding: 10px;
            font-size: 16px;
        }
    </style>
</head>
<body>

<h1>Chat Interface with Streaming & Context</h1>

<div id="chatBox"></div>
<input type="text" id="userInput" placeholder="Type a message..." onkeydown="if(event.key === 'Enter') sendMessage()">

<script>
    let conversationHistory = [];

    function displayMessage(role, content) {
        const chatBox = document.getElementById('chatBox');
        const messageDiv = document.createElement('div');
        messageDiv.className = `message ${role}`;

        const formattedContent = content.replace(/\\n/g, '<br>'); // 解析 \n 为 <br>

        messageDiv.innerHTML = formattedContent; // 使用 innerHTML 显示换行格式内容

        chatBox.appendChild(messageDiv);
        chatBox.scrollTop = chatBox.scrollHeight;
        return messageDiv;
    }

    function sendMessage() {
        const userInput = document.getElementById('userInput');
        const messageContent = userInput.value.trim();

        if (!messageContent) return;

        displayMessage('user', messageContent);
        userInput.value = '';

        conversationHistory.push({ role: 'user', content: messageContent });

        startSSE(conversationHistory);
    }

    function startSSE(messages) {
        const url = 'http://localhost:8098/ai/chat-stream';

        fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'text/event-stream'
            },
            body: JSON.stringify(messages)
        }).then(response => {
            if (!response.ok) {
                throw new Error('Network response was not ok');
            }

            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let buffer = '';
            let assistantMessageDiv = displayMessage('assistant', ''); // 空元素用于后续更新
            let accumulatedData = '';

            return new ReadableStream({
                start(controller) {
                    function read() {
                        reader.read().then(({ done, value }) => {
                            if (done) {
                                controller.close();
                                conversationHistory.push({ role: 'assistant', content: accumulatedData });
                                return;
                            }

                            buffer += decoder.decode(value, { stream: true });
                            const eventBlocks = buffer.split("\n\n");
                            buffer = eventBlocks.pop();

                            eventBlocks.forEach(eventBlock => {
                                const lines = eventBlock.split("\n");
                                let eventData = { data: '' };

                                lines.forEach(line => {
                                    if (line.startsWith("data:")) {
                                        eventData.data += line.substring(5);
                                    }
                                });

                                if (eventData.data) {
                                    accumulatedData += eventData.data.replace(/\\n/g, '\n');
                                    assistantMessageDiv.innerHTML = accumulatedData;
                                    document.getElementById('chatBox').scrollTop = document.getElementById('chatBox').scrollHeight;
                                }
                            });

                            read();
                        });
                    }

                    read();
                }
            });
        }).catch(error => {
            console.error('Fetch error:', error);
            displayMessage('assistant', 'Error: Unable to fetch response');
        });
    }
</script>

</body>
</html>
